package com.mo.tools.encrypt;


import org.springframework.util.Base64Utils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * @name: AESUtil
 * @description:
 * @author: Yang Xingfu
 * @date: 2020-07-16 14:51
 **/
public class AESUtil {

    public static byte[] encrypt(String content, String seed) {
        try {
            /**通过key创建AES生产者*/
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            /**利用密码作为随机数初始化种子*/
            /**加密是没有关系，SecureRandom是生产安全随机数序列,password.getBytes()是随机数种子，只要种子相同生成的随机序列就一样，故只有密码才能解密*/
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(seed.getBytes());
            keyGenerator.init(128, secureRandom);
            /** 根据用户密码，生成一个密钥*/
            SecretKey secretKey = keyGenerator.generateKey();
            /**返回基本编码格式的密钥，如果此密钥不支持编码，则返回null*/
            byte[] enCodeFormat = secretKey.getEncoded();
            /**转换为AES专用密钥*/
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            /**创建密码器*/
            Cipher cipher = Cipher.getInstance("AES");
            byte[] byteContent = content.getBytes("utf-8");
            /**初始化加密模式*/
            cipher.init(Cipher.ENCRYPT_MODE, key);
            /**加密*/
            byte[] result = cipher.doFinal(byteContent);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * description: AES加密
     * @author Yang Xingfu
     * @date 2020/7/16 15:12
     * @param plaintText 明文
     * @param seed 种子数据
     * @return java.lang.String Base64加密数据
     */
    public static String encryptString (String plaintText, String seed) {
        String cipherText = null;
        try {
            byte[] decrypt = encrypt(plaintText, seed);
            cipherText = Base64Utils.encodeToString(decrypt);
        } catch (Exception e) {
            throw new RuntimeException("编码转换异常");
        }

        return cipherText;
    }

    public static byte[] decrypt(byte[] content, String seed) {
        try {
            /**创建AES的Key生产者*/
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(seed.getBytes());
            keyGenerator.init(128, secureRandom);
            /**根据用户密码，生成一个密钥*/
            SecretKey secretKey = keyGenerator.generateKey();
            /**返回基本编码格式的密钥*/
            byte[] enCodeFormat = secretKey.getEncoded();
            /**转换为AES专用密钥*/
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            /**创建密码器*/
            Cipher cipher = Cipher.getInstance("AES");
            /**初始化为解密模式的密码器*/
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] result = cipher.doFinal(content);
            return result;

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * description: aes解码
     * @author Yang Xingfu
     * @date 2020/7/16 15:11
     * @param cipherText Base64加密数据
     * @param seed 种子
     * @return java.lang.String 解密数据
     */
    public static String decryptString(String cipherText, String seed) {
        byte[] bytes = Base64Utils.decodeFromString(cipherText);
        byte[] decrypt = decrypt(bytes, seed);
        String decryptString = null;
        try {
            decryptString =  new String(decrypt, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException("编码转换异常");
        }

        return decryptString;
    }

}
